/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlets;

import be.ugent.medirem.logic.GpRemote;
import be.ugent.medirem.logic.MeasurementRemote;
import be.ugent.medirem.logic.MedicationRemote;
import be.ugent.medirem.logic.PatientRemote;
import be.ugent.medirem.logic.PrescriptionRemote;
import be.ugent.medirem.logic.TaskRemote;
import be.ugent.medirem.persistence.entity.details.MeasurementDetails;
import be.ugent.medirem.persistence.entity.details.MeasurementTypeDetails;
import be.ugent.medirem.persistence.entity.details.MedicationDetails;
import be.ugent.medirem.persistence.entity.details.MedicationTaskDetails;
import be.ugent.medirem.persistence.entity.details.PatientDetails;
import be.ugent.medirem.persistence.entity.details.PrescriptionDetails;
import be.ugent.medirem.persistence.entity.values.GpValues;
import be.ugent.medirem.persistence.entity.values.MeasurementTypeValues;
import be.ugent.medirem.persistence.entity.values.MeasurementValues;
import be.ugent.medirem.persistence.entity.values.PatientValues;
import be.ugent.medirem.persistence.entity.values.PrescriptionValues;
import be.ugent.medirem.persistence.exception.EntityNotFoundException;
import be.ugent.medirem.persistence.util.DateFormatter;
import java.io.IOException;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Simon
 */
public class InitServlet extends HttpServlet {

    @EJB
    private MedicationRemote medicationRemote;
    @EJB
    private TaskRemote taskRemote;
    @EJB
    private PrescriptionRemote prescriptionRemote;
    @EJB
    private MeasurementRemote measurementRemote;
    @EJB
    private PatientRemote patientRemote;
    @EJB
    private GpRemote gpRemote;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Add some GPs
//            Long gp1 = gpRemote.create(new GpDetails("test", "Doctor Simon", "Buelens"), "test");
//            gpRemote.create(new GpDetails("test2", "Doctor Roelie", "Roelens"), "ja");

//            // Add locations
//            LocationDetails loc = new LocationDetails("Toffe straat", 1, 9000, "Gent", "Belgie", "09/3123145", "juij@tof.be");
//        try {
//            gpRemote.updateGpLocation(gp1, null, loc);
//        } catch (EntityNotFoundException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (IllegalArgumentException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        }
//            initCode(gp1);
//            request.setAttribute("view", "init_empty.jsp");
//            request.getRequestDispatcher("template.jsp").forward(request, response);

        String username = request.getUserPrincipal().getName();

        request.setAttribute("user", username);
        Long gpId = gpRemote.getGpId(username);
        initCode(gpId);
    }

    private void initCode(Long gpId) {
        Long p1 = null;
        try {
            p1 = this.initPatient();
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.initGP(gpId, p1);
        Long m1 = this.initMedicationsAndMeasurements(p1);
        this.initPrescriptions(gpId, p1, m1);
        this.initTasks(p1);
    }

    private Long initPatient() throws IllegalArgumentException, EntityNotFoundException {
        Long gp = gpRemote.create(new GpValues("demo", "demo", "Simon", "Buelens"));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Metod", "Savio", "Metod", "Savio", DateFormatter.convert("280/1977", "D/yyyy"), "A-", "987704794", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Caratacos", "Lindon", "Caratacos", "Lindon", DateFormatter.convert("192/1977", "D/yyyy"), "B-", "638249049", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Traian", "Ireneusz", "Traian", "Ireneusz", DateFormatter.convert("66/1958", "D/yyyy"), "O+", "139790901", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Farid", "Colm", "Farid", "Colm", DateFormatter.convert("198/1961", "D/yyyy"), "A+", "904840415", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ernest", "Boris", "Ernest", "Boris", DateFormatter.convert("233/1990", "D/yyyy"), "A+", "933081842", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Graeme", "Jamsheed", "Graeme", "Jamsheed", DateFormatter.convert("73/1974", "D/yyyy"), "O-", "958268617", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Clint", "Tarou", "Clint", "Tarou", DateFormatter.convert("232/1982", "D/yyyy"), "A-", "782951702", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ventseslav", "Delroy", "Ventseslav", "Delroy", DateFormatter.convert("15/1993", "D/yyyy"), "AB+", "687273854", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Bohdan", "Justin", "Bohdan", "Justin", DateFormatter.convert("42/1949", "D/yyyy"), "B-", "618499444", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Taras", "Shariah", "Taras", "Shariah", DateFormatter.convert("330/1958", "D/yyyy"), "AB+", "304410183", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Eckbert", "Gerben", "Eckbert", "Gerben", DateFormatter.convert("344/1949", "D/yyyy"), "AB+", "301694260", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Darius", "Ashanti", "Darius", "Ashanti", DateFormatter.convert("16/1955", "D/yyyy"), "O-", "225027270", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ragnarr", "Bartolomej", "Ragnarr", "Bartolomej", DateFormatter.convert("343/1965", "D/yyyy"), "O-", "299022735", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Aatami", "Pantheras", "Aatami", "Pantheras", DateFormatter.convert("277/1999", "D/yyyy"), "A-", "306491819", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Walerian", "Matth&auml;us", "Walerian", "Matth&auml;us", DateFormatter.convert("49/1978", "D/yyyy"), "O-", "867665316", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Herbie", "Wim", "Herbie", "Wim", DateFormatter.convert("195/1993", "D/yyyy"), "A-", "373964614", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Amilcare", "Erastos", "Amilcare", "Erastos", DateFormatter.convert("220/1958", "D/yyyy"), "B-", "873747582", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Herman", "Adalberht", "Herman", "Adalberht", DateFormatter.convert("282/1971", "D/yyyy"), "A+", "139629258", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Valentin", "Ewan", "Valentin", "Ewan", DateFormatter.convert("220/1956", "D/yyyy"), "AB+", "903463707", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Zephyrus", "Paulus", "Zephyrus", "Paulus", DateFormatter.convert("293/1978", "D/yyyy"), "A-", "672247064", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Hartley", "Curtis", "Hartley", "Curtis", DateFormatter.convert("345/1952", "D/yyyy"), "O+", "887126326", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Shinobu", "Ferdy", "Shinobu", "Ferdy", DateFormatter.convert("49/1978", "D/yyyy"), "O-", "337792475", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ozanne", "Shripati", "Ozanne", "Shripati", DateFormatter.convert("74/1969", "D/yyyy"), "A-", "980376521", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Amando", "Liber", "Amando", "Liber", DateFormatter.convert("287/1940", "D/yyyy"), "AB+", "523609423", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ritchie", "Rosario", "Ritchie", "Rosario", DateFormatter.convert("259/1942", "D/yyyy"), "O-", "888317972", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Tucker", "Aroldo", "Tucker", "Aroldo", DateFormatter.convert("276/1950", "D/yyyy"), "B-", "268111421", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Aias", "Temel", "Aias", "Temel", DateFormatter.convert("158/1964", "D/yyyy"), "B+", "198348354", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Oskar", "Eg&iacute;dio", "Oskar", "Eg&iacute;dio", DateFormatter.convert("109/1964", "D/yyyy"), "O-", "196849790", null)));
        gp = gpRemote.create(new GpValues("doctor", "test", "Thomas", "Roelens"));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Nudd", "Damodar", "Nudd", "Damodar", DateFormatter.convert("69/1963", "D/yyyy"), "O+", "569340754", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Karcsi", "Abner", "Karcsi", "Abner", DateFormatter.convert("321/1945", "D/yyyy"), "O-", "514800353", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Julek", "Mirza", "Julek", "Mirza", DateFormatter.convert("249/1985", "D/yyyy"), "AB-", "885681357", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Sieffre", "Alexander", "Sieffre", "Alexander", DateFormatter.convert("344/1998", "D/yyyy"), "AB+", "248527076", null)));
        gpRemote.addPatient(gp, patientRemote.createPatient(new PatientValues(null, "Ingi", "Rui", "Ingi", "Rui", DateFormatter.convert("181/1974", "D/yyyy"), "A+", "132897368", null)));

//        Long p1 = patientRemote.createPatient("p1", "p", "012122141");
//        patientRemote.createPatient("p2", "p", "012122141");
//        patientRemote.createPatient("p3", "p", "012122141");
//        try {
//            GregorianCalendar g = new GregorianCalendar(1988, 0, 12); // Warning 0 = Jan
//
//            patientRemote.updatePatient(new PatientDetails(p1, "Thomas", "Roelens", g.getTime(), "A-"));
//            patientRemote.updatePatient(p1, null, new LocationDetails("Heidelbergstraat", 12, 9000, "Gent", "Belgie", "09/31231145", "juij2@tof.be"));
//        } catch (EntityNotFoundException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (IllegalArgumentException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        List<PatientDetails> allPList = patientRemote.getAllPatients();
//        System.out.println("ALL PATIENTS: ");
//        for (PatientDetails pd : allPList) {
//            System.out.println("Patient : " + pd.getUsername());
//        }
//        Long id = patientRemote.getPatientId("p1");
//        return p1;
        return null;
    }

    private void initGP(Long gpId, Long pId) {
        try {
            gpRemote.addPatient(gpId, pId);
            List<PatientDetails> pList = gpRemote.getPatients(gpId);
            System.out.println("PATIENTS OF GP id: " + gpId);
            for (PatientDetails pd : pList) {
                System.out.println("Patient : " + pd.getUsername());
            }
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private Long initMedicationsAndMeasurements(Long pId) {
        medicationRemote.createUnit("cl");
        medicationRemote.createUnit("dl");
        Long id1 = medicationRemote.createUnit("kg");
        medicationRemote.createUnit("g");
        Long id2 = medicationRemote.createUnit("cm");

        MeasurementTypeValues v = new MeasurementTypeValues();
        v.setName("gewicht");
        v.setUnitId(id1);
        v = new MeasurementTypeValues();
        v.setName("lengte");
        v.setUnitId(id2);
        id1 = measurementRemote.createMeasurementType(v);
        id2 = measurementRemote.createMeasurementType(v);

        MeasurementValues mv = new MeasurementValues();
        mv.setTypeId(id1);
        mv.setValue(85.21);
        mv.setDateTaken(new Date());
        measurementRemote.addMeasurement(pId, mv);
        GregorianCalendar gc = new GregorianCalendar(2009, 11, 1, 18, 21);
        mv = new MeasurementValues();
        mv.setTypeId(id1);
        mv.setValue(64.21);
        mv.setDateTaken(gc.getTime());
        measurementRemote.addMeasurement(pId, mv);
        mv = new MeasurementValues();
        mv.setTypeId(id2);
        mv.setValue(185.21);
        mv.setDateTaken(new Date());
        measurementRemote.addMeasurement(pId, mv);


        List<MeasurementTypeDetails> mL = measurementRemote.getAllMeasurementTypes();
        System.out.println("Measurement Types:");
        for (MeasurementTypeDetails d : mL) {
            System.out.println(d.getName() + " in " + d.getUnit());
        }

        List<MeasurementDetails> measL = measurementRemote.getAllMeasurements(pId);

        System.out.println("Measurements of patient :" + pId);
        for (MeasurementDetails d : measL) {
            System.out.println("Type: " + d.getType() + ", value: " + d.getMeasurementValue() + ", date: " + d.getDateTaken());
        }

        MeasurementDetails d = measurementRemote.getLatestMeasurement(pId, "gewicht");
        System.out.println("LATEST gewicht measurement of patient :" + pId);
        System.out.println("Type: " + d.getType() + ", value: " + d.getMeasurementValue() + ", date: " + d.getDateTaken());

        Long m1 = null;
        Long m2 = null;
//        try {
//            m1 = medicationRemote.createMedication(new MedicationDetails("dieetpil", 10.0, "cl", "gewicht"));
//            m2 = medicationRemote.createMedication(new MedicationDetails("Medi2", 23.0, "dl"));
//            medicationRemote.createMedication(new MedicationDetails("Medi3", 11.0, "kg"));
//        } catch (IllegalArgumentException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (EntityNotFoundException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        }
//
//        try {
//            medicationRemote.updateMedication(m2, new MedicationDetails("MediUpdated", 0, null));
//        } catch (IllegalArgumentException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (EntityNotFoundException ex) {
//            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
//        }
        return m1;
    }

    private void initPrescriptions(Long gpId, Long pId, Long mId) {
        GregorianCalendar gc = new GregorianCalendar(2009, 11, 6, 12, 22);
        GregorianCalendar gc2 = new GregorianCalendar(2009, 11, 8, 13, 22);
        GregorianCalendar gc3 = new GregorianCalendar(2009, 11, 2, 23, 22);
        GregorianCalendar gc4 = new GregorianCalendar(2009, 11, 3, 13, 22);
        PrescriptionValues p = new PrescriptionValues();
        p.setDosageDosage(20);
        p.setDosageIsFixed(true);
        p.setDosageUnit("cl");
        p.setEndTime(gc.getTime());
        p.setFrequency(12);
        p.setGpId(gpId);
        p.setMedicationId(mId);
        p.setRemarks("Soms");
        p.setStartTime(gc3.getTime());
        prescriptionRemote.prescribeMedication(pId, p);
        p = new PrescriptionValues();
        p.setDosageIsFixed(false);
        p.setEndTime(gc2.getTime());
        p.setFrequency(2);
        p.setGpId(gpId);
        p.setMedicationId(mId);
        p.setRemarks("Variable dosage");
        p.setStartTime(gc4.getTime());
        // Pas op, medication heeft een measurementType nodig om webservice te kunnen oproepen
        prescriptionRemote.prescribeMedication(pId, p);


        List<PrescriptionDetails> pList = prescriptionRemote.getPrescriptions(pId);
        System.out.println("PRESCRIPTIONS OF PATIENT " + pId + " :");
        for (PrescriptionDetails d : pList) {
            MedicationDetails mDetails = null;
            try {
                mDetails = medicationRemote.getMedicationDetails(mId);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
            } catch (EntityNotFoundException ex) {
                Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(d.getPrescriptionId() + " : medi name: " + mDetails.getName() + ", dosage is " + (d.isDosageIsFixed() ? "fixed" : "variable") +
                    ", dose: " + d.getDosageDosage() + ", freq: " + d.getFrequency() + ", endtime: " + d.getEndTime().toString());
        }
    }

    private void initTasks(Long pId) {
        try {
            System.out.println("TASK STATUSSES: ");
            for (String s : taskRemote.getAllTaskStatus()) {
                System.out.println(s);
            }

            System.out.println("ALL TASKS OF PATIENT " + pId);
            List<MedicationTaskDetails> tasks = taskRemote.getAllTasks(pId);
            for (MedicationTaskDetails t : tasks) {
                System.out.println(t.getPrescription().getPrescriptionId() + " , status: " + t.getStatus() + ", tasktime: " + t.getTaskTime());
            }

            System.out.println("NEXT TASK OF PATIENT " + pId);
//            MedicationTaskDetails d = taskRemote.getNextTask(pId);
//            System.out.println(d.getPrescriptionId() + " , status: " + d.getStatus() + ", tasktime: " + d.getTaskTime());

            System.out.println("Complete next task ");
//            taskRemote.updateTaskStatus(d.getTaskId(), pId, TaskStatus.COMPLETED);

            System.out.println("Completed tasks:  ");
            List<MedicationTaskDetails> tasks2 = taskRemote.getAllCompletedTasks(pId);
            for (MedicationTaskDetails t : tasks2) {
                System.out.println(t.getPrescription().getPrescriptionId() + " , status: " + t.getStatus() + ", tasktime: " + t.getTaskTime() + ", compl: " + t.getCompletionTime());
            }

        } catch (IllegalArgumentException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(InitServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
